package org.codeblue.support.json;

import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.PropertyPreFilter;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * Created by jl.hu on 2017/4/12.
 */
public class NicePropertyPreFilter implements PropertyPreFilter {

    private Set<TypeNameBean> includes;
    private Set<TypeNameBean> excludes;

    public NicePropertyPreFilter(){}

    public NicePropertyPreFilter(String includes){
        setIncludes(includes);
    }
    /**
     * 格式 eg:user[id,name,pwd];order[id,name,status]
     *
     * @param fields 包含字段
     */
    public NicePropertyPreFilter setIncludes(String fields) {
        this.includes = putTypeNameToSet(fields);
        return this;
    }


    /**
     * 格式 eg:user[id,name,pwd];order[id,name,status]
     *
     * @param fields 排除字段
     */
    public NicePropertyPreFilter setExcudes(String fields) {
        this.excludes = putTypeNameToSet(fields);
        return this;
    }


    private Set<TypeNameBean> putTypeNameToSet(String fields) {
        Set<TypeNameBean> sets = new HashSet<TypeNameBean>();
        if (StringUtils.isEmpty(fields)) {
            return sets;
        }
        String[] objects = fields.split(";");
        if (objects.length == 0) {
            return sets;
        }
        for (String object : objects) {
            object.substring(0, object.indexOf("["));
            int openToken = object.indexOf("[");
            int closeToken = object.indexOf("]");
            String type = object.substring(0, openToken);
            String names[] = object.substring(openToken + 1, closeToken).split(",");
            for (String name : names) {
                TypeNameBean entity = new TypeNameBean(type, name);
                sets.add(entity);
            }
        }
        return sets;
    }

    public boolean apply(JSONSerializer jsonSerializer, Object o, String name) {
        String typeName = o.getClass().getSimpleName().toLowerCase();
        System.out.println("type: "+ typeName +"  name: " + name);
        TypeNameBean propertiyBean = new TypeNameBean(typeName, name);

        if(o instanceof Map){
            return true;
        }

        //默认全部显示
        if (CollectionUtils.isEmpty(includes) && CollectionUtils.isEmpty(excludes)) {
            return true;
        }

        boolean containIncludes = true; //默认OK
        boolean unContainExcludes = true; //默认OK

        if (!CollectionUtils.isEmpty(includes)) {
            containIncludes = includes.contains(propertiyBean);
        }
        if (!CollectionUtils.isEmpty(excludes)) {
            unContainExcludes = !excludes.contains(propertiyBean);
        }

        return containIncludes && unContainExcludes;
    }


    class TypeNameBean {
        String type;
        String name;

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public TypeNameBean(String type, String name) {
            this.type = type;
            this.name = name;
        }

        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            TypeNameBean bean = (TypeNameBean) o;

            if (!type.equals(bean.type)) return false;
            return name.equals(bean.name);

        }

        public int hashCode() {
            int result = type.hashCode();
            result = 31 * result + name.hashCode();
            return result;
        }
    }
}
